package com.gewu.bluetoothflow



import android.app.Activity
import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.provider.Settings
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.view.animation.LinearInterpolator
import android.widget.ImageView
import android.widget.PopupMenu
import android.widget.PopupWindow
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.eciot.ble_demo_kotlin.ECBLE
import com.gewu.bluetoothflow.adapter.MenuAdapter
import com.gewu.bluetoothflow.adapter.SearchDeviceAdapter
import com.gewu.bluetoothflow.bean.BleDeviceInfo
import com.gewu.bluetoothflow.bean.DeviceInfo
import com.gewu.bluetoothflow.databinding.ActivityMainBinding
import com.gewu.bluetoothflow.db.DeviceInfoBean
import com.gewu.bluetoothflow.tools.PreferencesManager
import com.gewu.bluetoothflow.ui.BaseActivity
import com.gewu.bluetoothflow.ui.DevConfigActivity
import com.gewu.bluetoothflow.ui.FlowDataActivity
import com.gewu.bluetoothflow.view.OnSwipeMenuItemClickListener
import com.gewu.bluetoothflow.view.SwipeMenu
import com.gewu.bluetoothflow.view.SwipeMenuCreator
import com.gewu.bluetoothflow.view.SwipeMenuItem
import com.gewu.bluetoothflow.view.SwipeMenuRecyclerView
import com.gewu.core.db.GewuDataBaseUtils
import com.google.gson.Gson
import pub.devrel.easypermissions.AppSettingsDialog
import java.util.*
import android.content.res.Configuration;
import android.provider.MediaStore
import com.gewu.bluetoothflow.MyApp.Companion.ACTION_SEND_DATA
import com.gewu.bluetoothflow.MyApp.Companion.EXTRA_DATA
import com.gewu.bluetoothflow.adapter.DataRefreshViewClickListener
import com.gewu.bluetoothflow.ui.DevInfoActivity
import com.gewu.bluetoothflow.ui.WifiDevConfigActivity


class MainActivity : BaseActivity(){
    val TAG: String = "MainActivity"
    private lateinit var listView: SwipeMenuRecyclerView
    private var mContext: Activity? = null
    private lateinit var adapter: MenuAdapter
    private var deviceListData: MutableList<DeviceInfo> = ArrayList()
    private var deviceListDataShow: MutableList<DeviceInfo> = ArrayList()

    private var historyDevice: MutableList<DeviceInfoBean> = ArrayList()

    private lateinit var mbinding:ActivityMainBinding ;
    val database by lazy { GewuDataBaseUtils.gewuDataBaseUtils}

    private lateinit var searchAdapter: SearchDeviceAdapter

    private  var currentDevice:BleDeviceInfo? = null
    private var DeviceInfo :String = ""
    private var dataRefresh : DataRefreshViewClickListener? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val lang = prefsManager!!.languages
        mbinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(mbinding!!.root)
        listView = mbinding.ryDevices
        mContext = this
        Log.d(TAG,"onCreate() --- $lang ")
        adapter = MenuAdapter(historyDevice)
        listView.setHasFixedSize(true)
        listView.itemAnimator = DefaultItemAnimator()

        listView.setSwipeMenuCreator(swipeMenuCreator)
        listView.setSwipeMenuItemClickListener(menuItemClickListener)

        val layoutManager= LinearLayoutManager(this)
        listView.adapter = adapter
        listView.itemAnimator = null
        layoutManager.orientation = RecyclerView.VERTICAL
        listView.layoutManager = layoutManager

        initPopuWindow()
        mbinding.llSN.setOnClickListener {
            goToDevInfo()
        }
        mbinding.llBusiness.setOnClickListener {
            goToDevInfo()
        }
        mbinding.llMainBattery.setOnClickListener {
            goToDevInfo()
        }
        mbinding.llSecondaryBattery.setOnClickListener {
            goToDevInfo()
        }

        mbinding.langswitch.setOnClickListener {
            val popupMenu = PopupMenu(this,it)
            val inflater = popupMenu.menuInflater
            popupMenu.setOnMenuItemClickListener {
                when(it.itemId){
                    R.id.ch -> {
                      Log.d(TAG,"==> "+Locale.SIMPLIFIED_CHINESE.language)
                       // switchLanguage(Locale.SIMPLIFIED_CHINESE.language,true)
                    }
                    R.id.en -> {
                        Log.d(TAG,"==>" +Locale.ENGLISH.language)
                       // switchLanguage(Locale.ENGLISH.language,true)
                    }
                }
                true
            }

            inflater.inflate(R.menu.popupmenu,popupMenu.menu)
            popupMenu.show()

        }

        mbinding.disconnect.setOnClickListener {
            ECBLE.closeBLEConnection()
            mbinding.currentDev.visibility = View.INVISIBLE
            mbinding.llSousuo.visibility = View.VISIBLE

           // openBluetoothAdapter()
        }
        mbinding.queryData.setOnClickListener {
           startActivity(Intent(this@MainActivity,FlowDataActivity::class.java))
        }

        mbinding.DevConfig.setOnClickListener {
            if (currentDevice == null){
                showToast(resources.getString(R.string.no_device_connection))
                return@setOnClickListener
            }
            var intent:Intent? = null
            if (currentDevice!!.id.startsWith("160")){ //红外单机版
                intent = Intent(this@MainActivity,DevConfigActivity::class.java)
            }else if (currentDevice!!.id.startsWith("161")){ //红外wifi版
                intent = Intent(this@MainActivity, WifiDevConfigActivity::class.java)
            }

            if (intent == null) return@setOnClickListener
             intent!!.putExtra("devInfo",DeviceInfo)
             startActivity(intent)
        }

        mbinding.searchDevConnect.setOnClickListener {
            showPopWindow()
            if (animator != null){
                loadingView.startAnimation(animator)
                loadingView.visibility = View.VISIBLE
            }
        }

        mbinding.viewHistorical.setOnClickListener {
            mbinding.viewHistorical.visibility = View.GONE
            mbinding.llHistory.visibility = View.VISIBLE
            listView.visibility = View.VISIBLE
        }

        mbinding.hideHistory.setOnClickListener {
            mbinding.viewHistorical.visibility = View.VISIBLE
            mbinding.llHistory.visibility = View.GONE
            listView.visibility = View.GONE
        }
        initBle()
        listRefresh()
        freshDevStatus()
    }

    private fun initBle(){
        deviceListData.clear()
        deviceListDataShow.clear()
        Thread{
            historyDevice.clear()
            val historyDev = database!!.deviceInfoDao().getAllDevice()
            historyDevice.addAll(historyDev)
            Log.d(TAG,"===> historyDevice : ${historyDevice.size}")
            runOnUiThread {
                listView.adapter!!.notifyDataSetChanged()
            }
        }.start()

        openBluetoothAdapter()
        ECBLE.setChineseTypeUTF8()

        ECBLE.onBLEConnectionStateChange { _: Boolean, _: Int, _: String? ->
            runOnUiThread {
                showToast(resources.getString(R.string.disconnected_bluetooth))
            }
        }
        //{"id":"2102024420001","time":"20250116134104","rxBat":60,"txBat":60,"pair":"False","model":"HE3(SI)","ver":"V1.0",
        // "open":"0000","close":"2310","dir":"onlyIn","storCyc":1}
        ECBLE.onBLECharacteristicValueChange { str: String, strHex: String ->
            Log.d(TAG,"-> ${str.length} :  "+ str )
            if (dataRefresh != null) {
                dataRefresh!!.dataRefresh(str)
            }
            if (!str.substring(str.length-5).contains("}"))return@onBLECharacteristicValueChange //   !str.endsWith("}")
            runOnUiThread {
                val intent = Intent()
                intent.setAction(ACTION_SEND_DATA)
                intent.putExtra(EXTRA_DATA,str)
                sendBroadcast(intent)
               // val timeStr: String = dateFormat.format(Date(System.currentTimeMillis()))
                currentDevice = Gson().fromJson(str,BleDeviceInfo::class.java)
                if (currentDevice!!.id.isNullOrEmpty()) return@runOnUiThread
                DeviceInfo = str
                freshDevStatus()
            }
        }
        /**
         * {"num":8,"state":"0","type":"0","data":[
         *   {"time":"24072909","in":1,"out":1},
         *   {"time":"24072910","in":1,"out":1},
         *   {"time":"24072911","in":1,"out":1},
         *   {"time":"24072912","in":1,"out":1},
         *   {"time":"24072913","in":1,"out":1},
         *   {"time":"24072914","in":1,"out":1},
         *   {"time":"24072915","in":1,"out":1},
         *   {"time":"24072916","in":1,"out":1}]}
         */
    }

    private fun freshDevStatus(){
        if (currentDevice != null){
            mbinding.llSousuo.visibility = View.GONE
            mbinding.currentDev.visibility = View.VISIBLE

            mbinding.devSn.setText(currentDevice!!.id)
            var startTime = "08:00"
            var endTime = "22:00"
            if (currentDevice!!.open.length == 4){
                 startTime = currentDevice!!.open.substring(0,2)+":"+currentDevice!!.open.substring(2,4)
            }
            if (currentDevice!!.close.length == 4){
                 endTime = currentDevice!!.close.substring(0,2)+":"+currentDevice!!.close.substring(2,4)
            }
            mbinding.bussinessHour.setText("$startTime-$endTime")
            if (currentDevice!!.devBat.toString().length > 0){
                mbinding.mainbattery.setText("${currentDevice!!.devBat}%")
                mbinding.llSecondaryBattery.visibility = View.GONE  //ll_secondary_battery
            }else{
                if (mbinding.llSecondaryBattery.visibility == View.GONE) {
                    mbinding.llSecondaryBattery.visibility = View.VISIBLE
                }
                mbinding.mainbattery.setText("${currentDevice!!.rxBat}%")
                mbinding.sendarybattery.setText("${currentDevice!!.txBat}%")
            }

        }else{
            mbinding.llSousuo.visibility = View.VISIBLE
            mbinding.currentDev.visibility = View.INVISIBLE
        }

    }


    /** Which state in US are you from
     *  菜单创建器。在Item要创建菜单的时候调用。
     */
    private val swipeMenuCreator: SwipeMenuCreator = object : SwipeMenuCreator {
        override fun onCreateMenu(
            swipeLeftMenu: SwipeMenu,
            swipeRightMenu: SwipeMenu,
            viewType: Int
        ) {
            val width = resources.getDimensionPixelSize(R.dimen.item_height)

            // MATCH_PARENT 自适应高度，保持和内容一样高；也可以指定菜单具体高度，也可以用WRAP_CONTENT。
            val height = ViewGroup.LayoutParams.MATCH_PARENT
            // 添加右侧的，如果不添加，则右侧不会出现菜单。
            run {


                val closeItem: SwipeMenuItem = SwipeMenuItem(mContext)
                    .setBackgroundDrawable(R.drawable.selector_purple)
                    .setText(resources.getString(R.string.connect))
                    .setTextColor(Color.WHITE)
                    .setWidth(width)
                    .setHeight(height)
                swipeRightMenu.addMenuItem(closeItem) // 添加一个按钮到右侧菜单。

                val deleteItem: SwipeMenuItem = SwipeMenuItem(mContext)
                    .setBackgroundDrawable(R.drawable.selector_red)
                    //.setImage(R.mipmap.ic_action_delete)
                    .setText(resources.getString(R.string.delete)) // 文字，还可以设置文字颜色，大小等。。
                    .setTextColor(Color.WHITE)
                    .setWidth(width)
                    .setHeight(height)
                swipeRightMenu.addMenuItem(deleteItem) // 添加一个按钮到右侧侧菜单。

/*
                val addItem: SwipeMenuItem = SwipeMenuItem(mContext)
                    .setBackgroundDrawable(R.drawable.selector_green)
                    .setText("添加")
                    .setTextColor(Color.WHITE)
                    .setWidth(width)
                    .setHeight(height)
                swipeRightMenu.addMenuItem(addItem) // 添加一个按钮到右侧菜单。

 */
            }
        }
    }

    /**
     * 菜单点击监听。
     */
    private val menuItemClickListener =
        OnSwipeMenuItemClickListener { closeable, adapterPosition, menuPosition, direction ->
            /**
             * Item的菜单被点击的时候调用。
             * @param closeable       closeable. 用来关闭菜单。
             * @param adapterPosition adapterPosition. 这个菜单所在的item在Adapter中position。
             * @param menuPosition    menuPosition. 这个菜单的position。比如你为某个Item创建了2个MenuItem，那么这个position可能是是 0、1，
             * @param direction       如果是左侧菜单，值是：SwipeMenuRecyclerView#LEFT_DIRECTION，如果是右侧菜单，值是：SwipeMenuRecyclerView#RIGHT_DIRECTION.
             */
            closeable.smoothCloseMenu() // 关闭被点击的菜单。

            if (direction == SwipeMenuRecyclerView.RIGHT_DIRECTION) {
//                Toast.makeText(
//                    this,
//                    "list第$adapterPosition; 右侧菜单第$menuPosition",
//                    Toast.LENGTH_SHORT
//                ).show()
            }
            else if (direction == SwipeMenuRecyclerView.LEFT_DIRECTION) {
//                Toast.makeText(
//                    this,
//                    "list第$adapterPosition; 左侧菜单第$menuPosition",
//                    Toast.LENGTH_SHORT
//                ).show()
            }

            // TODO 如果是删除：推荐调用Adapter.notifyItemRemoved(position)，不推荐Adapter.notifyDataSetChanged();
            if (menuPosition == 1) { // 删除按钮被点击。
                if (historyDevice.size > adapterPosition) {
                    historyDevice.removeAt(adapterPosition)
                }
                adapter.notifyItemRemoved(adapterPosition)
            }else if (menuPosition == 0){ //连接 按钮被点击
                val deviceInfo = historyDevice[adapterPosition]
                if (!deviceInfo.enableConnect){
                    showToast(resources.getString(R.string.cannot_connect))
                    return@OnSwipeMenuItemClickListener
                }
                Log.d(TAG,"====> itemClick ${deviceInfo.name}")
              //  val strTime = dateFormat.format(System.currentTimeMillis())
                showConnectDialog()
                delayHideConnDialog(30000)
                ECBLE.onBLEConnectionStateChange { ok: Boolean, errCode: Int, errMsg: String ->
                    if (ok) {
                        val devDao = database!!.deviceInfoDao()
                        val bean = devDao.getDeviceById(deviceInfo.strId)
                        if (bean.size > 0) {
                            val devBean = bean.get(0)
                            devBean.name = deviceInfo.name
                            devBean.lastTime = System.currentTimeMillis() //strTime
                            devDao.update(devBean)
                        }
                    }
                    runOnUiThread {
                        try {
                        Thread.sleep(3000)
                        }catch (e:Exception){
                         Log.d(TAG,"sleep:"+e.message.toString())
                        }
                        hideConnectDialog()
                        if (ok) {
                            val state = ECBLE.writeBLECharacteristicValue("{\"info\":\"get\"}", false)
                            if (state){
                                connected = true
                                showToast(resources.getString(R.string.connect_ble_success))
                            }
                        } else {
                            connected = false
                            if (errCode == 1){
                                showToast(resources.getString(R.string.disconnected_bluetooth))
                            }else {
                                showToast(resources.getString(R.string.connect_ble_fail) +",errCode=$errCode,errMsg=$errMsg")
                            }
                        }
                    }
                }
                ECBLE.createBLEConnection(this@MainActivity, deviceInfo.strId)
            }
        }


    override fun onStart() {
        super.onStart()
        Log.d(TAG,"onStart() ---")

    }

    private fun openBluetoothAdapter() {
        ECBLE.onBluetoothAdapterStateChange { ok: Boolean, errCode: Int, errMsg: String ->
            runOnUiThread {
                if (!ok) {
                    showAlert(
                        resources.getString(R.string.tip),
                        "openBluetoothAdapter error,errCode=$errCode,errMsg=$errMsg"
                    ) {
                        if (errCode == 10001) {
                            //蓝牙开关没有打开
                            startActivity(Intent(Settings.ACTION_BLUETOOTH_SETTINGS))
                        }
                        if (errCode == 10002) {
                            //定位开关没有打开
                            startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
                        }
                        if (errCode == 10003) {
                            AppSettingsDialog.Builder(this)
                                .setTitle( resources.getString(R.string.tip))
                                .setRationale(getString(R.string.open_positiong_permission))
                                .build().show()
                        }
                        //获取蓝牙连接附近设备的权限失败
                        if (errCode == 10004) {
                            AppSettingsDialog.Builder(this)
                                .setTitle( resources.getString(R.string.tip))
                                .setRationale(getString(R.string.open_blepermission_allow_connect_nearby_dev))
                                .build().show()
                        }
                    }
                } else {
                    Log.d(TAG, "openBluetoothAdapter ok")
                    startBluetoothDevicesDiscovery()
                }
            }
        }
        ECBLE.openBluetoothAdapter(this)
    }

    private fun startBluetoothDevicesDiscovery() {
        ECBLE.onBluetoothDeviceFound { id: String, name: String, mac: String, rssi: Int ->
            if (!name.contains("foorir"))return@onBluetoothDeviceFound
            runOnUiThread {
                var isExist = false
                for (tempDevice in deviceListData) {
                    if (tempDevice.strId == id) {
                        tempDevice.rssi = rssi
                        tempDevice.name = name
                        isExist = true
                        break
                    }
                }
                if (!isExist) {
                    Log.d(TAG, "Discovery  $id-$name|$mac|$rssi")
                    deviceListData.add(DeviceInfo(id, name, mac, rssi,""))
                }
            }
        }
        ECBLE.startBluetoothDevicesDiscovery(this)
    }

    private fun listRefresh() {
        Handler().postDelayed({
            deviceListDataShow.clear()
            for (tempDevice in deviceListData) {
                deviceListDataShow.add(tempDevice)
            }

            var changeState = false
            for (history in historyDevice){
                deviceListDataShow.forEach {
                    if (history.strId.equals(it.strId)){
                        history.enableConnect = true
                        changeState = true
                    }
                }
            }
            if (changeState) {
                listView.adapter!!.notifyDataSetChanged()
            }

            searchAdapter.notifyDataSetChanged()
            if (animator != null && loadingView.visibility == View.VISIBLE){
                loadingView.clearAnimation()
                loadingView.visibility = View.GONE
            }
            //Log.d(TAG,"listRefresh -- ")
            listRefresh()
        }, 6000)
    }


    private var connected = false
    private lateinit var connectDialog: ProgressDialog
    fun showConnectDialog() {
        runOnUiThread {
            if (!::connectDialog.isInitialized){
                connectDialog = ProgressDialog(this@MainActivity)
                connectDialog.setMessage(resources.getString(R.string.connecting)+"...")
                connectDialog.setCancelable(false)
            }
            connectDialog.show()
        }
    }

    private fun hideConnectDialog() {
        connectDialog.dismiss()
    }
    var mTimer:Timer? = null
    private fun delayHideConnDialog(time:Long){
        if (mTimer != null){
            mTimer!!.cancel()
            mTimer = null
        }
        mTimer = Timer()
        mTimer!!.schedule(
            object : TimerTask() {
                override fun run() {
                    runOnUiThread {
                        if (connectDialog != null && connectDialog.isShowing) {
                            connectDialog!!.dismiss()
                            if (!connected){
                                showToast(resources.getString(R.string.connect_ble_fail))
                            }
                        }
                    }
                }
            }, time
        )

    }

    private lateinit var popupWindow: PopupWindow
    private lateinit var searchView: RecyclerView
    private lateinit var loadingView: ImageView
    private var  animator : Animation? = null

    fun initPopuWindow(){
         val pwView = LayoutInflater.from(this).inflate(R.layout.activity_pw,null)
         searchView = pwView.findViewById(R.id.rySearchDev)
         popupWindow = PopupWindow(pwView,ViewGroup.LayoutParams.MATCH_PARENT
        ,ViewGroup.LayoutParams.WRAP_CONTENT)
        initRecyclerView()
        popupWindow.isOutsideTouchable = true
        popupWindow.isTouchable = true
        popupWindow.isFocusable = true

        popupWindow.animationStyle = R.style.PopupAnimation
        loadingView = pwView.findViewById<ImageView>(R.id.loadingImg)
        animator = AnimationUtils.loadAnimation(this,R.anim.rotate)
        val lin = LinearInterpolator()
        animator!!.setInterpolator(lin)
        popupWindow.setOnDismissListener {
            backgroundAlpha(1f)
        }

    }

    fun showPopWindow(){
        popupWindow.showAtLocation(mbinding.root,Gravity.BOTTOM,0,0)
        backgroundAlpha(0.7f)
    }

    fun backgroundAlpha(fl: Float){
         val lp = window.attributes
         lp.alpha = fl
         window.attributes = lp
     }
    fun initRecyclerView(){
        searchAdapter = SearchDeviceAdapter(deviceListDataShow)
        val layoutManager= LinearLayoutManager(this)
        searchView.adapter = searchAdapter
        searchView.itemAnimator = null
         layoutManager.orientation = RecyclerView.VERTICAL
        searchView.layoutManager = layoutManager

        searchAdapter.setOnItemClick(object: SearchDeviceAdapter.ItemViewClickListener {
            override fun itemClick(i: Int) {
                val deviceInfo = deviceListDataShow[i]
                Log.d(TAG,"====> itemClick ${deviceInfo.name}")
               // val strTime = dateFormat.format(System.currentTimeMillis())
                popupWindow.dismiss()
                showConnectDialog()
                delayHideConnDialog(30000)
                ECBLE.onBLEConnectionStateChange { ok: Boolean, errCode: Int, errMsg: String ->
                    if (ok) {
                        val devDao = database!!.deviceInfoDao()
                        val bean = devDao.getDeviceById(deviceInfo.strId)
                        if (bean.size > 0) {
                            val devBean = bean.get(0)
                            devBean.name = deviceInfo.name
                            devBean.lastTime = System.currentTimeMillis()
                            devDao.update(devBean)
                        } else {
                            val devBean = DeviceInfoBean(
                                strId = deviceInfo.strId,
                                name = deviceInfo.name,
                                mac = deviceInfo.mac,
                                rssi = "${deviceInfo.rssi}",
                                lastTime = System.currentTimeMillis()
                            )
                            val num = devDao.insertGenerateId(devBean)
                        }
                    }
                    runOnUiThread {
                        Thread.sleep(3000)
                        hideConnectDialog()
                        if (ok) {
                           val state = ECBLE.writeBLECharacteristicValue("{\"info\":\"get\"}", false)
                            if (state){
                                showToast(resources.getString(R.string.connect_ble_success))
                            }
                        } else {
                            if (errCode == 1){
                                showToast(resources.getString(R.string.disconnected_bluetooth))
                            }else {
                                showToast(resources.getString(R.string.connect_ble_fail)+",errCode=$errCode,errMsg=$errMsg")
                            }
                        }
                    }
                }
                ECBLE.createBLEConnection(this@MainActivity, deviceInfo.strId)
            }
        })

    }


    fun goToDevInfo(){
        if (currentDevice == null){
            showToast(resources.getString(R.string.no_device_connection))
            return
        }
        val intent = Intent(this@MainActivity,DevInfoActivity::class.java)
        intent.putExtra("devInfo",DeviceInfo)
        startActivity(intent)
    }

    override fun onStop() {
        super.onStop()
        Log.d(TAG,"onStop() ---")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG,"onDestroy() ---")
        ECBLE.onBLECharacteristicValueChange { _, _ -> }
        ECBLE.onBLEConnectionStateChange { _, _, _ -> }
        ECBLE.closeBLEConnection()
    }
}